﻿#include "../../interface/IDrag.h"

namespace swui
{
	void IDrag::_mouse_event_(ctlMouseEvent* me)
	{
		if(me->eventModel != ctlMouseEventModel::cut) return;
		if(!(me->eventType == ctlMouseEventType::move && _drag_moving))
			ctlRoot::_mouse_event_(me);
		if(!isDragable()) return;
		//初始化拖放信息
		ctlNotifyEvent ne;
		ctlNotifyDrag nd;
		bool isAllow = true;
		ne.eventType = ctlNotifyEventType::drag;
		ne.info = &nd;
		nd.isAllow = &isAllow;
		nd.mousePos = me->mousePos;

		if(me->eventType == ctlMouseEventType::leftDown)
		{
			nd.position = ctlPoint(getLeft(), getTop());
			nd.state = ctlNotifyDrag::begin;
			//记录鼠标位置
			_capture_mouse_move();
			_drag_rawmouse = me->absolutePos;
			_drag_rawpos = nd.position;
			_notify_event_(&ne);
			if(nd.isAllow) _drag_moving = true;
		} else if(me->eventType == ctlMouseEventType::leftUp) {
			nd.position = ctlPoint(getLeft(), getTop());
			nd.state = ctlNotifyDrag::end;
			_release_mouse_move();
			_notify_event_(&ne);
			if(nd.isAllow) _drag_moving = false;
		} else if(me->eventType == ctlMouseEventType::move && _drag_moving) {
			ctlPoint prepos = nd.position = ctlPoint(getLeft(), getTop());
			nd.state = ctlNotifyDrag::move;
			if((unsigned)getDragableDir() & (unsigned)ctlDirection::x)
			{
				//如果允许 x 方向拖动
				nd.position.x = me->absolutePos.x - _drag_rawmouse.x + _drag_rawpos.x;
				if(limitDragableRange())
				{
					if(_drag_rect.x > nd.position.x)
					{
						if(_drag_dealoverrange) nd.position.x = _drag_rect.x;
						else nd.position.x = getLeft();
					} else if(_drag_rect.x + _drag_rect.cx < nd.position.x + getWidth()) {
						if(_drag_dealoverrange) nd.position.x = _drag_rect.x + _drag_rect.cx - getWidth();
						else nd.position.x = getLeft();
					}
				}
			}
			if((unsigned)getDragableDir() & (unsigned)ctlDirection::y)
			{
				//如果允许 y 方向拖动
				nd.position.y = me->absolutePos.y - _drag_rawmouse.y + _drag_rawpos.y;
				if(limitDragableRange())
				{
					if(_drag_rect.y > nd.position.y)
					{
						if(_drag_dealoverrange) nd.position.y = _drag_rect.y;
						else nd.position.y = getTop();
					} else if(_drag_rect.y + _drag_rect.cy < nd.position.y + getHeight()) {
						if(_drag_dealoverrange) nd.position.y = _drag_rect.y + _drag_rect.cy - getHeight();
						else nd.position.y = getTop();
					}
				}
			}
			//如果位置确实发生了改变
			if(prepos.x != nd.position.x || prepos.y != nd.position.y)
			{  
				_notify_event_(&ne);
				if(nd.isAllow)	move(nd.position);
			}
		}
	}
}